A mailbox provides a synchronized communication channel between two concurrent processes — typically a Generator and a Driver in a SystemVerilog testbench.


🧩 Concept Overview

This pattern models a realistic testbench environment where different verification components operate at their own pace.


Exchanging Objects Using a Mailbox

program mailbox_example(bus_if.TB bus, ...);

    // -----------------------
    // Generator Class
    // -----------------------
    class Generator;
        Transaction tr;
        mailbox mbx;

        function new(mailbox mbx);
            this.mbx = mbx;
        endfunction

        task run;
            repeat (10) begin
                tr = new;
                assert(tr.randomize);
                mbx.put(tr); // Send transaction to mailbox
            end
        endtask
    endclass


    // -----------------------
    // Driver Class
    // -----------------------
    class Driver;
        Transaction tr;
        mailbox mbx;

        function new(mailbox mbx);
            this.mbx = mbx;
        endfunction

        task run;
            repeat (10) begin
                mbx.get(tr); // Receive transaction from mailbox
                @(posedge busif.cb.ack);
                bus.cb.kind <= tr.kind;
                ...
            end
        endtask
    endclass


    // -----------------------
    // Testbench Setup
    // -----------------------
    mailbox mbx;   // Shared mailbox between generator & driver
    Generator gen;
    Driver drv;

    initial begin
        mbx = new;           // Create the mailbox
        gen = new(mbx);      // Pass mailbox handle to generator
        drv = new(mbx);      // Pass mailbox handle to driver

        fork
            gen.run();       // Spawn generator thread
            drv.run();       // Spawn driver thread
        join
    end

endprogram


🧠 Explanation

Component Role Behavior
Generator Produces transactions Randomizes and sends each transaction via mbx.put(tr)
Mailbox (mbx) Communication channel Holds transactions until the driver retrieves them
Driver Consumes transactions Calls mbx.get(tr) to fetch the next transaction and drives it to the bus

🔄 Data Flow Summary

Generator ── put(tr) ─▶ [ Mailbox FIFO ] ── get(tr) ─▶ Driver

Both operations automatically handle synchronization between threads.


🧱 Key Takeaways